package org.esti.model.dao.impl;

import org.esti.model.User;
import org.esti.model.dao.UserDAO;
import org.esti.model.exceptions.UserDoesNotExistException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Artem Loginov (logart)
 */

/**
 * {@inheritDoc}
 */
@Repository
public class UserDAOimpl implements UserDAO {

    private static final Logger LOGGER = Logger.getLogger(UserDAOimpl.class.getName());

    @PersistenceContext
    private EntityManager entityManager;

    /**
     * {@inheritDoc}
     */
    @Transactional(readOnly = true)
    @Override
    public boolean isUserExist(User user) {
        try {
            getByLogin(user.getLogin());
        } catch (NoResultException ex) {
            return false;
        } catch (UserDoesNotExistException ex) {
            return false;
        }

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Transactional
    @Override
    public User add(User user) {
        return entityManager.merge(user);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional(readOnly = true)
    @Override
    public User getByLogin(String login) {
        try {
            Query query = entityManager.createQuery(
                    "SELECT u FROM User u WHERE u.login=:login"
            );
            query.setParameter("login", login);
            return (User) query.getSingleResult();
        } catch (NoResultException ex) {
            throw new UserDoesNotExistException(ex);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Transactional
    @Override
    public User update(User user) {
        LOGGER.log(Level.INFO, "user id is: " + user.getId());
        return entityManager.merge(user);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional(readOnly = true)
    @Override
    public List<User> getAllUsers() {
        return (List<User>) entityManager.createQuery("SELECT u FROM User u").getResultList();
    }

    /**
     * {@inheritDoc}
     */
    @Transactional(readOnly = true)
    @Override
    public List<User> getUsersByKeyWord(String keyword) {

        Query query = entityManager.createQuery("SELECT u FROM User u WHERE " +
                "(" +
                "(u.login LIKE :keyword)" +
                "OR(u.name LIKE :keyword)" +
                "OR(u.middleName LIKE :keyword)" +
                "OR(u.surname LIKE :keyword)" +
                "OR(u.email LIKE :keyword)" +
                ")");

        query.setParameter("keyword", '%' + keyword + '%');

        return (List<User>) query.getResultList();
    }
}
